package me.leon.lib4x.rxlifecycle

import android.content.Context
import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager
import io.reactivex.BackpressureStrategy
import io.reactivex.FlowableTransformer
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.schedulers.Schedulers
import io.reactivex.subjects.BehaviorSubject

/**
 * Author : Leon Shih
 * Time   :2018/8/13 0013 14:29
 * E-mail :deadogone@gmail.com    :
 * Desc   : RxLifecycle
 */
object RxLifecycle {

    private const val TAG = "rxLifecycle"
    lateinit var ob: BehaviorSubject<Life>
    fun with(ctx: Context): RxLifecycle {

        when (ctx) {
            is AppCompatActivity -> {
                with(ctx.supportFragmentManager)
            }
            is Fragment -> {
                with(ctx.childFragmentManager)
            }

        }
        return this
    }


    fun with(fm: FragmentManager) {
        val fragment: BindingFragment = fm.findFragmentByTag(TAG) as BindingFragment?
                ?: BindingFragment()
        this.ob = fragment.mLifeCycleBehavior
        fm.beginTransaction().apply {
            if (null == fm.findFragmentByTag(TAG))
                add(fragment, TAG)
            else if (fragment.isDetached)
                attach(fragment)
            commit()
        }

    }


    /**
     * @param <T>
     * @return
     * @Desc 线程切换 使用io密集型操作， 例如网络请求,数据库操作
    </T> */
    fun <T> rxSwitch(): FlowableTransformer<T, T> {

        return FlowableTransformer<T, T> {
            it.subscribeOn(Schedulers.io())
                    .unsubscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
        }
    }

    fun <T> bindToLifeCycle(ordinal: Int): FlowableTransformer<T, T> {
        return FlowableTransformer {
            ob.onNext(Life.ATTACH)
            it.takeUntil(ob.toFlowable(BackpressureStrategy.BUFFER).filter { item -> item.ordinal >= ordinal })
        }
    }

    fun <T> bindToDestroy(): FlowableTransformer<T, T> {
        return FlowableTransformer {
            ob.onNext(Life.ATTACH)
            it.takeUntil(ob.toFlowable(BackpressureStrategy.BUFFER).filter { item -> item.ordinal >= Life.DESTROY_VIEW.ordinal })
        }
    }
}

